/// <reference path='../_all.ts' />

module PiiS {
    'use strict';

    /**
      *   The main controller for the app. The controller:
      *   - Creates new user.
      *   - Downloads the list of all movies.
      *   - Performs rating.
      */
    export class MainController {

        /**
          * This method is called on prototype during registration into IoC container. 
          * It provides $injector with information about dependencies to be injected into constructor
          * it is better to have it close to the constructor, because the parameters must match in count and type.
          */
        public injection(): any[] {
            return [
                '$scope',
                '$location',
                '$routeParams',
                '$http',
                MainController
            ]
        }

        /** Dependencies are injected via AngularJS $injector
          * controller's name is registered in App.ts and invoked from ng-controller attribute in index.html.
          */
        constructor
            (
            private $scope: IMainScope,
            private $location: ng.ILocationService,
            private $routeParams: any,
            private $http: ng.IHttpService
            )
        {
            //Initializing variables.
            $scope.loggedPerson = null;
            $scope.movieList = null;
            $scope.loading = true;
            $scope.registeredUsers = 0;
            $scope.votesCast = 0;

            // Adding event handlers to the scope, so they could be bound from view/HTML
            // these lambdas fix this keyword in JS world.
            $scope.GetMovieList = () => this.GetMovieList();
            $scope.RateMovie = (movie: Movie, value: number) => this.RateMovie(movie, value);

            $http.get('api/Person/' + $routeParams.personId)
                .success((result: Person, status, headers) => {
                    $scope.loggedPerson = result;
                })
                .error((result, status, headers) => {
                    console.log("Error while loading person data.");
                    this.$location.path("/person");
                });

            $scope.GetMovieList();
            this.loadCount();
        }

        /**
          * Downloads whole movie list from the remote server.
          */
        GetMovieList(): void {
            this.$http.get('api/Movie/' + this.$routeParams.personId)
                .success((result: Movie[], status, headers) => {
                    this.$scope.loading = false;
                    this.$scope.movieList = result;
                    
                    setTimeout(() => {
                        this.$scope.movieList.forEach((value, index) => {
                                this.$http.jsonp('http://api.themoviedb.org/3/movie/' + value.TMDBId + '?api_key=d20b778e2233be6a4066a4e952164d2a&callback=JSON_CALLBACK')
                                    .success((result, status, headers) => {
                                        value.CoverUrl = 'http://d3gtl9l2a4fn1j.cloudfront.net/t/p/w185' + result.poster_path;
                                        value.Description = result.overview;
                                        value.ReleaseDate = result.release_date;
                                        value.Tagline = result.tagline;
                                    })
                                    .error((result, status, headers) => {
                                        console.log("Error while loading movie details");
                                    });
                        });
                    }, 0);

                    this.$scope.$watchCollection
                })
                .error((result, status, headers) => {
                    console.log("Error while loading movie list.");
                    this.$location.path("/person");
                });
        }

        /**
          * Assigns a rating for a given movie/person pair.
          */
        RateMovie(movie: Movie, selectedValue?: number): void {            
            if (selectedValue != null)
                selectedValue = selectedValue - 1;

            this.$http.post('api/Evaluation', new Evaluation(0, movie.Id, this.$scope.loggedPerson.Id, selectedValue))
                .success((result: Evaluation, status, headers) =>
                {
                    movie.Evaluation = result.EvaluationValue;
                    console.log("Movie rated correctly.");
                })
                .error((result, status, headers) =>
                {
                    console.log("Error while rating a movie.");
                });
        }

        loadCount(): void {
            this.$http.get('/api/Person')
                .success((result, status, headers) => {
                    this.$scope.registeredUsers = result.m_Item1;
                    this.$scope.votesCast = result.m_Item2;
                }).error((result, status, headers) => {
                    console.log("Error while loading person and votes count.");
                });
            setTimeout(() => {
                this.loadCount();
            }, 10000);
        }
    }
}